using System;
using System.IO;
using System.Text;
using System.ServiceProcess ;
using System.ComponentModel ;
using Microsoft.Win32;
using SharePoint.ImportExport.Core;

namespace SharePoint2003.Import
{
	/// <summary>
	/// Summary description for ServiceManager.
	/// </summary>
	internal class ServiceManager
	{

		
		/// <summary>
		///	W3SVC => World Wide Web Publishing Service 
		/// </summary>
		private const string ServiceName = "W3SVC";
		/// <summary>
		/// Service Error enumerator
		/// 
		/// </summary>
		public enum ServiceError
		{
			/// <summary>
			/// ERROR_SUCCESS    = 0,
			/// </summary>
			ERROR_SUCCESS    = 0,
			/// <summary>
			/// ERROR_INVALID_OPERATION = 1
			/// </summary>
			ERROR_INVALID_OPERATION = 1,
			/// <summary>
			/// ERROR_WIN32_EXCEPTION = 2
			/// </summary>
			ERROR_WIN32_EXCEPTION = 2
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="serviceName"></param>
		/// <returns></returns>
		private ServiceError Start(string serviceName)
		{
			ServiceController controller = null;
			
			try
			{
				controller = new ServiceController (serviceName);
			
				if(	ServiceControllerStatus.StopPending == controller.Status )
				{
					controller.WaitForStatus(ServiceControllerStatus.Stopped); 
				}
				else if( ServiceControllerStatus.PausePending == controller.Status )
				{
					controller.WaitForStatus(ServiceControllerStatus.Paused); 
				}
				else if( ServiceControllerStatus.StartPending == controller.Status )
				{
					controller.WaitForStatus(ServiceControllerStatus.Running); 
				}
				else if( ServiceControllerStatus.ContinuePending == controller.Status )
				{
					controller.WaitForStatus(ServiceControllerStatus.Running); 
				}

				// By now, the service will either be in stopped, paused or running state
				// The service has to be stopped when you try to start it!!
				// So if it is paused, stop it first.
				if(ServiceControllerStatus.Paused == controller.Status)
				{
					Stop(serviceName);
				}

				// Now if it is not running, start it
				if(ServiceControllerStatus.Running != controller.Status)
				{
					controller.Start ();
					controller.WaitForStatus (ServiceControllerStatus.Running);
				}

				//If it was already running, do nothing?
				return ServiceError.ERROR_SUCCESS ;
			}
			catch(Win32Exception wExc)
			{
				Logger.Log(ErrorLevel.Error,"Start Service Exception "+wExc.Message);  //LogID: ServiceManager_StartService_2
				return ServiceError.ERROR_WIN32_EXCEPTION ;
			}
			catch(InvalidOperationException iExc)
			{
				Logger.Log(ErrorLevel.Error,"Start Service Invalid Operation Exception "+iExc.Message);  //LogID: ServiceManager_StartService_2
				return ServiceError.ERROR_INVALID_OPERATION ;
			}
			finally
			{
				if(null != controller) controller.Close();
			}
		}

/// <summary>
/// 
/// </summary>
/// <param name="serviceName"></param>
/// <returns></returns>
		private ServiceError Stop(string serviceName)
		{
			ServiceController controller = new ServiceController (serviceName);

			try
			{
				if(	ServiceControllerStatus.StopPending == controller.Status )
				{
					controller.WaitForStatus(ServiceControllerStatus.Stopped); 
				}
				else if( ServiceControllerStatus.PausePending == controller.Status )
				{
					controller.WaitForStatus(ServiceControllerStatus.Paused); 
				}
				else if( ServiceControllerStatus.StartPending == controller.Status )
				{
					controller.WaitForStatus(ServiceControllerStatus.Running); 
				}
				else if( ServiceControllerStatus.ContinuePending == controller.Status )
				{
					controller.WaitForStatus(ServiceControllerStatus.Running); 
				}
				
				// By now, the service will either be in stopped, paused or running state
				if( ServiceControllerStatus.Stopped != controller.Status )
				{
					controller.Stop ();
					controller.WaitForStatus (ServiceControllerStatus.Stopped);
				}	
				// If it was already stopped, do nothing?
				return ServiceError.ERROR_SUCCESS;

			}
			catch(Win32Exception wExc)
			{
				Logger.Log(ErrorLevel.Error,"Stop Service Exception "+wExc.Message);  //LogID: ServiceManager_StartService_2
				return ServiceError.ERROR_WIN32_EXCEPTION ; 
			}
			catch(InvalidOperationException iExc)
			{
				Logger.Log(ErrorLevel.Error,"Stop Service Invalid Operation Exception "+iExc.Message);  //LogID: ServiceManager_StartService_2
				return ServiceError.ERROR_INVALID_OPERATION ;
			}
			finally
			{
				if(null != controller) controller.Close();
			}
		}

/// <summary>
/// 
/// </summary>
/// <returns></returns>
		public ServiceError IISReset()
		{
			Logger.Log(ErrorLevel.Information,"Performing an IISReset");
			ServiceError error = Stop(ServiceName);

			//If Stop was not successful, bail with error code
			if(ServiceError.ERROR_SUCCESS != error)
			{
				return error;
			}

			error = Start(ServiceName);
			return error;
		}
	}
}
